﻿/*
 * MeasureUnit
 * 
 * initial implementation : 20.11.2008
 *
 * Copyright (c) Adam Sida, asida@centrum.cz.
 * All rights reserved.
 * 
 * for license see Petra.Gis.License.txt
 */
using System;
using System.IO;
using System.Runtime.Serialization;
//using System.Collections.Generic;
using System.Runtime.Serialization.Json;


namespace Petra.Gis.ReferenceSystemServices
{
  /// <summary>
  /// Abstract base class that represents coordinate system measure unit.
  /// Coordinate system uses specific unit to save coordinates into.
  /// typical unit is meter, degree, mile,...
  /// </summary>
  [DataContract(Name="UNIT")]
  public abstract class MeasureUnit
  {


    //internal static List<MeasureUnit> AllUnits;


    //static MeasureUnit()
    //{
    //  AllUnits = new List<MeasureUnit>();
    //}
    



    /// <summary>
    /// xaml constructor
    /// </summary>
    protected MeasureUnit() { }





    protected MeasureUnit(Metadata metadata)
    {
      Metadata = metadata;
    }





    //protected Metadata _metadata;
    /// <summary>
    /// sets or returns Unit metadata
    /// </summary>
    [DataMember (Name="INFO")]
    public Metadata Metadata
    { get; set; }






    /// <summary>
    /// compares <c>this</c> measure unit to given and determines if both has same meaning,
    /// regardles to their names or metadata.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public abstract bool EqualParams(object obj);





    public static bool operator ==(MeasureUnit left, MeasureUnit right)
    {
      //when input is null
      if (!(left is MeasureUnit) && !(right is MeasureUnit))
        return true;
      else if (!(left is MeasureUnit && right is MeasureUnit))
        return false;

      return left.EqualParams(right);
    }





    public static bool operator !=(MeasureUnit left, MeasureUnit right)
    {
      //when input is null
      //when input is null
      if (!(left is MeasureUnit) && !(right is MeasureUnit))
        return false;
      else if (!(left is MeasureUnit && right is MeasureUnit))
        return true;

      return !left.EqualParams(right);
    }





    /// <summary>
    /// parses <c>MeasureUnit</c> from json string. String must be UTF-8 encoded.
    /// </summary>
    /// <param name="strUTF8Json">JSON string with valid MeasureUnit (DistanceUnit or AngulaUrnit)</param>
    /// <returns>instance of MeasureUnit or null when error parsing JSON</returns>
    public static MeasureUnit Parse(string strUTF8Json)
    {

      System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
      MemoryStream ms = new MemoryStream(encoding.GetBytes(strUTF8Json));

      //try parse DistanceUnit
      try
      {
        DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(DistanceUnit));
        return (DistanceUnit)json.ReadObject(ms);
      }
      catch (Exception e){ }

      //try parse AngularUnit
      try
      {
        DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(AngularUnit));
        return (AngularUnit)json.ReadObject(ms);
      }
      catch (Exception e) { }

      //// init static classes
      //// this will fill the AllUnits List ;-)
      //MeasureUnit tmp = AngularUnit.Gon;
      //tmp = DistanceUnit.Meter;

      //foreach (MeasureUnit su in AllUnits)
      //  if (su.Metadata.Name.ToLower() == unitName.ToLower())
      //    return su;

      return null;
    }


  }
}
